package webapp.mvc.services.impl;

import com.google.common.base.Function;
import com.zoowii.jpa_utils.extension.Paginator;
import com.zoowii.jpa_utils.query.Expr;
import com.zoowii.jpa_utils.util.ListUtil;
import com.zoowii.jpa_utils.util.StringUtil;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.stereotype.Service;
import webapp.mvc.controllers.forms.CreateProductForm;
import webapp.mvc.controllers.forms.UpdateProductForm;
import webapp.mvc.enums.IntBooleans;
import webapp.mvc.exceptions.ProductException;
import webapp.mvc.models.*;
import webapp.mvc.services.IProductService;
import webapp.mvc.utils.TimeUtil;

import java.util.List;

@Service
public class ProductService implements IProductService {
    @Override
    public List<ProductEntity> getProducts(String shopId, Paginator paginator) {
        paginator.getOrders().add(Pair.of("collectCount", false));
        paginator.getOrders().add(Pair.of("commentCount", false));
        paginator.getOrders().add(Pair.of("modifyTime", false));
        return ProductEntity.find.getProductsOfShop(shopId, paginator);
    }

    @Override
    public List<ProductEntity> searchProducts(String keyword, Paginator paginator) {
        if (!StringUtil.isEmpty(keyword)) {
            keyword = "%" + keyword + "%";
            paginator = paginator.addExpression(Expr.createOR(Expr.createLIKE("name", keyword),
                    Expr.createLIKE("description", keyword)));
        }
        paginator.getOrders().add(Pair.of("collectCount", false));
        paginator.getOrders().add(Pair.of("commentCount", false));
        paginator.getOrders().add(Pair.of("modifyTime", false));
        paginator = paginator.eq("deleted", IntBooleans.FALSE);
        return ProductEntity.find.findByPaginator(paginator);
    }

    @Override
    public List<ProductChangeRequestEntity> getProductChangeRequests(Paginator paginator) {
        paginator.getOrders().add(Pair.of("createTime", false));
        paginator = paginator.eq("deleted", IntBooleans.FALSE);
        List<ProductChangeRequestEntity> productChangeRequestEntities = ProductChangeRequestEntity.find.findByPaginator(paginator);
        ListUtil.map(productChangeRequestEntities, new Function<ProductChangeRequestEntity, Void>() {
            @Override
            public Void apply(ProductChangeRequestEntity productChangeRequestEntity) {
                productChangeRequestEntity.setProduct(ProductEntity.find.byId(productChangeRequestEntity.getProductId()));
                return null;
            }
        });
        return productChangeRequestEntities;
    }

    @Override
    public ProductEntity agreeProductChangeRequest(String requestId) {
        ProductChangeRequestEntity productChangeRequestEntity = ProductChangeRequestEntity.find.byId(requestId);
        if (productChangeRequestEntity == null) {
            return null;
        }
        boolean isNew = StringUtil.isEmpty(productChangeRequestEntity.getProductId());
        ProductEntity productEntity;
        if (isNew) {
            productEntity = new ProductEntity();
            productEntity.setShopId(productChangeRequestEntity.getShopId());
        } else {
            productEntity = ProductEntity.find.byId(productChangeRequestEntity.getProductId());
            if (productEntity == null) {
                productChangeRequestEntity.delete();
                return null;
            }
        }
        productEntity.setDescription(productChangeRequestEntity.getDescription());
        productEntity.setLogoUrl(productChangeRequestEntity.getLogoUrl());
        productEntity.setPrice(productChangeRequestEntity.getPrice());
        productEntity.setDiscount(productChangeRequestEntity.getDiscount());
        productEntity.setName(productChangeRequestEntity.getName());
        productEntity.setModifyTime(TimeUtil.currentTimestamp());
        if (isNew) {
            productEntity.save();
        } else {
            productEntity.update();
        }
        productChangeRequestEntity.setDeleted(IntBooleans.TRUE);
        productChangeRequestEntity.setPassed(IntBooleans.TRUE);
        productChangeRequestEntity.setModifyTime(TimeUtil.currentTimestamp());
        productChangeRequestEntity.update();
        return productEntity;
    }

    @Override
    public ProductChangeRequestEntity disagreeProductChangeRequest(String requestId) {
        ProductChangeRequestEntity productChangeRequestEntity = ProductChangeRequestEntity.find.byId(requestId);
        if (productChangeRequestEntity == null) {
            return null;
        }
        productChangeRequestEntity.setDeleted(IntBooleans.TRUE);
        productChangeRequestEntity.setModifyTime(TimeUtil.currentTimestamp());
        productChangeRequestEntity.update();
        return productChangeRequestEntity;
    }

    @Override
    public ProductEntity createProduct(String requestUserId, CreateProductForm createProductForm) throws ProductException {
        if(ProductEntity.find.findByName(createProductForm.getName())!=null) {
            throw new ProductException("商品名称" + createProductForm.getName() + "已经存在");
        }
        ProductChangeRequestEntity productChangeRequestEntity = new ProductChangeRequestEntity();
        productChangeRequestEntity.setName(createProductForm.getName());
        productChangeRequestEntity.setRequestUserId(requestUserId);
        productChangeRequestEntity.setDescription(createProductForm.getDescription());
        productChangeRequestEntity.setShopId(createProductForm.getShopId());
        productChangeRequestEntity.setLogoUrl(createProductForm.getLogoUrl());
        if (createProductForm.getDiscount() >= 0) {
            productChangeRequestEntity.setDiscount(createProductForm.getDiscount());
        }
        productChangeRequestEntity.setPrice(createProductForm.getPrice());
        productChangeRequestEntity.save();
//        ProductEntity productEntity = new ProductEntity();
//        productEntity.setShopId(createProductForm.getShopId());
//        productEntity.setDescription(createProductForm.getDescription());
//        productEntity.setLogoUrl(createProductForm.getLogoUrl());
//        productEntity.setPrice(createProductForm.getPrice());
//        productEntity.setName(createProductForm.getName());
//        productEntity.save();
        return null;
    }

    @Override
    public ProductEntity updateProduct(String requestUserId, String productId, UpdateProductForm updateProductForm) throws ProductException {
        ProductEntity productEntity = ProductEntity.find.byId(productId);
        if(productEntity == null || productEntity.getDeleted() != IntBooleans.FALSE) {
            throw new ProductException("找不到商品" + productId);
        }
        ProductChangeRequestEntity productChangeRequestEntity = new ProductChangeRequestEntity();
        productChangeRequestEntity.setRequestUserId(requestUserId);
        productChangeRequestEntity.setProductId(productEntity.getId());
        productChangeRequestEntity.setPrice(productEntity.getPrice());
        productChangeRequestEntity.setDiscount(productEntity.getDiscount());
        productChangeRequestEntity.setName(productEntity.getName());
        productChangeRequestEntity.setDescription(productEntity.getDescription());
        productChangeRequestEntity.setLogoUrl(productEntity.getLogoUrl());
        if(!StringUtil.isEmpty(updateProductForm.getName())) {
            if (!productEntity.getName().equals(updateProductForm.getName())) {
                ProductEntity productWithNewName = ProductEntity.find.findByName(updateProductForm.getName());
                if(productWithNewName != null) {
                    throw new ProductException("商品名称" + updateProductForm.getName() + "已经存在");
                }
//                productEntity.setName(updateProductForm.getName());
                productChangeRequestEntity.setName(updateProductForm.getName());
            }
        }
        if(!StringUtil.isEmpty(updateProductForm.getDescription())) {
//            productEntity.setDescription(updateProductForm.getDescription());
            productChangeRequestEntity.setDescription(updateProductForm.getDescription());
        }
        if(!StringUtil.isEmpty(updateProductForm.getLogoUrl())) {
//            productEntity.setLogoUrl(updateProductForm.getLogoUrl());
            productChangeRequestEntity.setLogoUrl(updateProductForm.getLogoUrl());
        }
        if (updateProductForm.getDiscount() >= 0) {
            productChangeRequestEntity.setDiscount(updateProductForm.getDiscount());
        }
//        productEntity.setPrice(updateProductForm.getPrice());
        productChangeRequestEntity.setPrice(updateProductForm.getPrice());
        productChangeRequestEntity.setShopId(productEntity.getShopId());
        productChangeRequestEntity.save();
//        productEntity.setModifyTime(TimeUtil.currentTimestamp());
//        productEntity.update();
        return productEntity;
    }

    @Override
    public ProductEntity findById(String id) {
        return ProductEntity.find.byId(id);
    }

    @Override
    public List<CommentEntity> getProductLatestComments(String productId, int limit) {
        return CommentEntity.find.where().eq("productId", productId).eq("deleted", IntBooleans.FALSE).limit(limit).orderBy("createTime", false).all();
    }

    @Override
    public List<CommentEntity> getComments(String productId, Paginator paginator) {
        paginator = paginator.eq("productId", productId).eq("deleted", IntBooleans.FALSE);
        paginator.getOrders().add(Pair.of("createTime", false));
        return CommentEntity.find.findByPaginator(paginator);
    }

    @Override
    public void deleteComments(List<String> ids) {
        for(String id : ids) {
            CommentEntity commentEntity = CommentEntity.find.byId(id);
            if(commentEntity!=null && commentEntity.getDeleted()!=IntBooleans.TRUE) {
                commentEntity.setDeleted(IntBooleans.TRUE);
                commentEntity.setModifyTime(TimeUtil.currentTimestamp());
                commentEntity.update();
                ProductEntity productEntity = findById(commentEntity.getProductId());
                if(productEntity!=null){
                    productEntity.setCommentCount(productEntity.getCommentCount() - 1);
                    productEntity.update();
                }
                ShopEntity shopEntity = ShopEntity.find.byId(commentEntity.getShopId());
                if(shopEntity!=null){
                    shopEntity.setCommentCount(shopEntity.getCommentCount()-1);
                    shopEntity.update();
                }
            }
        }
    }

    @Override
    public CommentEntity createProductComment(String userId, String productId, String title, String content) throws ProductException{
        if(StringUtil.isEmpty(content)) {
            throw new ProductException("评论内容不可为空");
        }
        ProductEntity productEntity = findById(productId);
        if(productEntity == null) {
            throw new ProductException("找不到商品" + productId);
        }
        CommentEntity commentEntity = new CommentEntity();
        commentEntity.setContent(content);
        commentEntity.setProductId(productId);
        commentEntity.setUserId(userId);
        commentEntity.setShopId(productEntity.getShopId());
        commentEntity.setTitle(title != null ? title : "");
        commentEntity.save();
        productEntity.setCommentCount(productEntity.getCommentCount() + 1);
        productEntity.update();
        ShopEntity shopEntity = ShopEntity.find.byId(productEntity.getShopId());
        if(shopEntity != null) {
            shopEntity.setCommentCount(shopEntity.getCommentCount() + 1);
            shopEntity.update();
        }
        return commentEntity;
    }

    @Override
    public void collectProduct(String productId, String userId) {
        if(StringUtil.isEmpty(productId) || StringUtil.isEmpty(userId)) {
            return;
        }
        ProductCollectEntity productCollectEntity = ProductCollectEntity.find.findByProductAndUser(productId, userId);
        if(productCollectEntity == null) {
            productCollectEntity = new ProductCollectEntity();
            productCollectEntity.setProductId(productId);
            productCollectEntity.setUserId(userId);
            productCollectEntity.save();
            ProductEntity productEntity = ProductEntity.find.byId(productId);
            if (productEntity != null) {
                productEntity.setCollectCount(productEntity.getCollectCount() + 1);
                productEntity.update();
            }
        }
    }

    @Override
    public void unCollectProduct(String productId, String userId) {
        if(StringUtil.isEmpty(productId) || StringUtil.isEmpty(userId)) {
            return;
        }
        ProductCollectEntity productCollectEntity = ProductCollectEntity.find.findByProductAndUser(productId, userId);
        if(productCollectEntity != null) {
            productCollectEntity.delete();
            ProductEntity productEntity = ProductEntity.find.byId(productId);
            if (productEntity != null) {
                productEntity.setCollectCount(productEntity.getCollectCount() - 1);
                if (productEntity.getCollectCount() < 0) {
                    productEntity.setCollectCount(0);
                }
                productEntity.update();
            }
        }
    }

    @Override
    public boolean isCollectedProduct(String productId, String userId) {
        if(StringUtil.isEmpty(productId) || StringUtil.isEmpty(userId)) {
            return false;
        }
        ProductCollectEntity productCollectEntity = ProductCollectEntity.find.findByProductAndUser(productId, userId);
        return productCollectEntity != null;
    }

    @Override
    public List<ProductEntity> getUserCollectedProducts(String userId, Paginator paginator) {
        return ProductCollectEntity.find.getCollectedProductsByUser(userId, paginator);
    }

    @Override
    public List<ProductEntity> getHotestProducts(int limit) {
        return ProductEntity.find.where().orderBy("commentCount", false).limit(limit).all();
    }
}
